﻿
Imports std
Imports lock_t = lock(Of locks.monitorlock)

Namespace locks
    Public Structure eventCombLock
        Implements ilock
        Private Const NOT_IN_USE As Boolean = False
        Private Const IN_USE As Boolean = Not NOT_IN_USE
        Private l As lock_t
        Private inuse As Boolean
        Private q As queue(Of void)

        Shared Sub New()
            assert([default](Of Boolean)() = NOT_IN_USE)
            assert([default](Of queue(Of void))() Is Nothing)
        End Sub

        Public Sub enter() Implements ilock.enter
            l.wait()
            If q Is Nothing Then
                q = New queue(Of void)()
            End If
            If inuse = IN_USE Then
                Dim v As void = Nothing
                assert_waitfor(v)
                assert(q.push(v))
            Else
                inuse = IN_USE
            End If
            l.release()
        End Sub

        Public Sub [exit]() Implements ilock.exit
            Dim v As void = Nothing
            l.wait()
            assert(inuse = IN_USE)
            If q.empty() Then
                inuse = NOT_IN_USE
            Else
                v = q.front()
                assert(q.pop())
                assert(Not v Is Nothing)
            End If
            l.release()
            If Not v Is Nothing Then
                v()
            End If
        End Sub

        Public Function thread_owned() As Boolean Implements ilock.thread_owned
            Return False
        End Function
    End Structure
End Namespace
